<!doctype html>
<title>SVGLength tests</title>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<div id="testcontainer">
  <svg width="1" height="1" visibility="hidden"> </svg>
</div>
<script>

var svg = document.querySelector("svg");

var EPSILON = Math.pow(2, -8);
var lengths = [10, 0, 360, 500, 90, 180, 45, 25.9];
var validUnits = {
    "" : 1,
    "%": 2,
    "em": 3,
    "ex": 4,
    "px": 5,
    "cm": 6,
    "mm": 7,
    "in": 8,
    "pt": 9,
    "pc": 10,
};

function createLength(valuestr) {
    var length = svg.createSVGLength();
    length.valueAsString = valuestr;
    return length;
}

function convertTo(value, unit, outunit) {
    var userUnits;
    var cssPixelsPerInch = 96;
    var cssPixelsPerCentimeter = cssPixelsPerInch / 2.54; //2.54 cm/in
    var cssPixelsPerMillimeter = cssPixelsPerCentimeter / 10;
    var cssPixelsPerPoint = cssPixelsPerInch / 72;
    var cssPixelsPerPica = cssPixelsPerInch / 6;

    switch(unit) {
        case "":
        case "px":
            userUnits = value;
            break;
        case "%":
        case "em":
        case "ex":
        case "rem":
        case "ch":
            return value;
        case "cm":
            userUnits = value * cssPixelsPerCentimeter;
            break;
        case "mm":
            userUnits = value * cssPixelsPerMillimeter;
            break;
        case "in":
            userUnits = value * cssPixelsPerInch;
            break;
        case "pt":
            userUnits = value * cssPixelsPerPoint;
            break;
        case "pc":
            userUnits = value * cssPixelsPerPica;
            break;
    }

    switch(outunit) {
        case "":
        case "px":
            return userUnits;
        case "%":
        case "em":
        case "ex":
        case "rem":
        case "ch":
            return value;
        case "cm":
            return userUnits / cssPixelsPerCentimeter;
        case "mm":
            return userUnits / cssPixelsPerMillimeter;
        case "in":
            return userUnits / cssPixelsPerInch;
        case "pt":
            return userUnits / cssPixelsPerPoint;
        case "pc":
            return userUnits / cssPixelsPerPica;
    }
}

test(function() {
  for (var unit in validUnits) {
    var length = createLength(10 + unit);
    assert_equals(length.unitType, validUnits[unit]);
  }
}, "Test valid unit types are accepted in valueAsString");

test(function() {
  var invalidUnits = {
    "rem": 1,
    "ch": 2
  };
  for (var unit in invalidUnits) {
    var length = createLength(10 + unit);
    assert_equals(length.unitType, SVGLength.SVG_LENGTHTYPE_UNKNOWN);
  }
}, "Test unit types that don't have a corresponding IDL constant");

test(function() {
  var unitConstants = {
    "UNKNOWN" : 0,
    "NUMBER": 1,
    "PERCENTAGE": 2,
    "EMS": 3,
    "EXS": 4,
    "PX": 5,
    "CM": 6,
    "MM": 7,
    "IN": 8,
    "PT": 9,
    "PC": 10,
  };
  for (var constant in unitConstants) {
    var str = "SVG_LENGTHTYPE_" + constant;
    assert_own_property(SVGLength, str, str + " should exist in SVGLength");
  }
}, "Test that unit constants that are supposed to be exposed are available");

test(function() {
  var nonexposedUnitConstants = {
    "REMS": 11,
    "CHS":12
  };
  for (var constant in nonexposedUnitConstants) {
    var str = "SVG_LENGTHTYPE_" + constant;
    assert_false(str in SVGLength, str + " should not be exposed in SVGLength");
  }
}, "Test that unit constants that are not supposed to be exposed are not available");

test(function() {
  for (var i = 0; i < validUnits.length; ++i) {
    var unit = validUnits[i];
    for (var j = 0; j < lengths.length; ++j) {
      var length = lengths[i];
      var value = createLength(length + unit);
      assert_equals(length, value.valueInSpecifiedUnits);
    }
  }
}, "Test result from valueInSpecifiedUnits");

test(function() {
  var nonRelativeUnits = ["px", "cm", "mm", "in", "pt", "pc"];

  for (var i = 0; i < lengths.length; ++i) {
    var length = lengths[i];
    for (var j = 0; j < nonRelativeUnits.length; ++j) {
      var unit = nonRelativeUnits[j];
      var lengthStr = length + unit;
      for (var k = 0; k < nonRelativeUnits.length; ++k) {
        var otherUnit = nonRelativeUnits[k];
        var svgLength = createLength(lengthStr);
        svgLength.convertToSpecifiedUnits(validUnits[otherUnit]);
        assert_approx_equals(svgLength.valueInSpecifiedUnits, convertTo(length, unit, otherUnit), EPSILON);
      }
    }
  }
}, "Test converting unit types for non-relative units");

test(function() {
  for (var i = 0; i < lengths.length; ++i) {
    var length = lengths[i];
    for (var j = 0; j < validUnits.length; ++j) {
      var unit = validUnits[j];
      var ref = createLength(length + unit);

      for (var k = 0; k < validUnits.length; ++k) {
        var otherUnit = validUnits[k];

        var value = createLength(47 + otherUnit);
        value.newValueSpecifiedUnits(unit, length);

        assert_equals(value.valueAsString, ref.valueAsString);
      }
    }
  }
}, "Test newValueSpecifiedUnits for each unit");

</script>

